//
// Created by zlf on 24-1-2.
//

#ifndef AUTODRIVE_PERCEPTION_MAP_MAP_DECODE_H
#define AUTODRIVE_PERCEPTION_MAP_MAP_DECODE_H

#include <memory>
#include <mutex>
#include <vector>

namespace autodrive {
namespace perception {

/// @brief declare map
struct Map;
/// @brief declare map filter implementation class
class MapDecoderImpl;

class MapDecoder final {
 public:
  MapDecoder();
  MapDecoder(MapDecoder &&) = delete;
  MapDecoder(const MapDecoder &) = delete;
  MapDecoder &operator=(MapDecoder &&) = delete;
  MapDecoder &operator=(const MapDecoder &) = delete;
  ~MapDecoder();

  struct MapDecoderParameter {
    std::uint32_t preds_number;
    std::uint32_t down_size;
    std::vector<float> net_range;
    std::vector<float> detection_range;
    std::vector<float> voxel_size;
    std::uint32_t type_offset;
    std::vector<int> multi_line;
    std::vector<int> min_pts_num;
    std::vector<float> merge_threshold;
    std::vector<float> start_cls_threshold;
    std::vector<float> cls_threshold;
    std::vector<float> vec_threshold;
    std::vector<float> dis_threshold;
    std::vector<float> keypoint_threshold;
    float dis_loss_weight;
  };

  /// @brief init
  /// @param para map decoder parameter
  /// @throw
  void Init(MapDecoderParameter const &para) noexcept(false);

  /// @brief is init flag
  /// @return init flag
  bool IsInit() noexcept;

  /// @brief
  /// @tparam _ScalerType
  /// @param dpuout_cls
  /// @param dpuout_reg
  /// @param cls
  /// @param cls_scale
  /// @param reg_scale
  /// @param map
  template <typename _ScalerType>
  void Decode(_ScalerType const *dpuout_cls, _ScalerType const *dpuout_reg,
              std::uint8_t cls, std::uint8_t cls_scale, std::uint8_t reg_scale,
              Map &map) noexcept(false);

 private:
  /// @brief  init call once flag
  mutable std::once_flag init_flag_;
  /// @brief map filter impl pointer
  std::shared_ptr<MapDecoderImpl> map_decoder_impl_ptr_;
};
}  // namespace perception
}  // namespace autodrive
#endif  // AUTODRIVE_PERCEPTION_MAP_MAP_DECODE_H
